﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

/// <summary>
/// EncryptUtils 的摘要说明
/// </summary>
public sealed class EncryptUtils
{
    #region Base64加密解密
    /// <summary>
    /// Base64加密
    /// </summary>
    /// <param name="input">需要加密的字符串</param>
    /// <returns></returns>
    public static string Base64Encrypt(string input)
    {
        return Base64Encrypt(input, new UTF8Encoding());
    }

    /// <summary>
    /// Base64加密
    /// </summary>
    /// <param name="input">需要加密的字符串</param>
    /// <param name="encode">字符编码</param>
    /// <returns></returns>
    public static string Base64Encrypt(string input, Encoding encode)
    {
        return Convert.ToBase64String(encode.GetBytes(input));
    }

    /// <summary>
    /// Base64解密
    /// </summary>
    /// <param name="input">需要解密的字符串</param>
    /// <returns></returns>
    public static string Base64Decrypt(string input)
    {
        return Base64Decrypt(input, new UTF8Encoding());
    }

    /// <summary>
    /// Base64解密
    /// </summary>
    /// <param name="input">需要解密的字符串</param>
    /// <param name="encode">字符的编码</param>
    /// <returns></returns>
    public static string Base64Decrypt(string input, Encoding encode)
    {
        return encode.GetString(Convert.FromBase64String(input));
    }
    #endregion

    #region DES加密解密
    /// <summary>
    /// DES加密
    /// </summary>
    /// <param name="data">加密数据</param>
    /// <param name="key">8位字符的密钥字符串</param>
    /// <param name="iv">8位字符的初始化向量字符串</param>
    /// <returns></returns>
    public static string DESEncrypt(string data, string key, string iv)
    {
        byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(key);
        byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(iv);

        DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
        int i = cryptoProvider.KeySize;
        MemoryStream ms = new MemoryStream();
        CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

        StreamWriter sw = new StreamWriter(cst);
        sw.Write(data);
        sw.Flush();
        cst.FlushFinalBlock();
        sw.Flush();
        return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
    }

    /// <summary>
    /// DES解密
    /// </summary>
    /// <param name="data">解密数据</param>
    /// <param name="key">8位字符的密钥字符串(需要和加密时相同)</param>
    /// <param name="iv">8位字符的初始化向量字符串(需要和加密时相同)</param>
    /// <returns></returns>
    public static string DESDecrypt(string data, string key, string iv)
    {
        byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(key);
        byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(iv);

        byte[] byEnc;
        try
        {
            byEnc = Convert.FromBase64String(data);
        }
        catch
        {
            return null;
        }

        DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
        MemoryStream ms = new MemoryStream(byEnc);
        CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
        StreamReader sr = new StreamReader(cst);
        return sr.ReadToEnd();
    }
    #endregion

    #region AES加密解密
    /// <summary>
    /// DES加密
    /// </summary>
    /// <param name="data">加密数据</param>
    /// <param name="key">8位字符的密钥字符串</param>
    /// <param name="iv">8位字符的初始化向量字符串</param>
    /// <returns></returns>
    public static string AesEncrypt(string plaintext, string key, string iv)
    {
        byte[] keyArray = Convert.FromBase64String(key);
        byte[] ivArray = Convert.FromBase64String(iv);
        UTF8Encoding utf8 = new UTF8Encoding();
        string ciphertext;

        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        using (ICryptoTransform encryptor = aes.CreateEncryptor(keyArray, ivArray))
        {
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
            byte[] bytes = utf8.GetBytes(plaintext);
            cs.Write(bytes, 0, bytes.Length);
            cs.FlushFinalBlock();
            ms.Position = 0;
            bytes = new byte[ms.Length];
            ms.Read(bytes, 0, bytes.Length);
            ciphertext = Convert.ToBase64String(bytes);
        }
        return ciphertext;
    }

    /// <summary>
    /// AES解密
    /// </summary>
    /// <param name="data">解密数据</param>
    /// <param name="key">8位字符的密钥字符串(需要和加密时相同)</param>
    /// <param name="iv">8位字符的初始化向量字符串(需要和加密时相同)</param>
    /// <returns></returns>
    public static string AesDecrypt(string ciphertext, string key, string iv)
    {
        byte[] keyArray = Convert.FromBase64String(key);
        byte[] ivArray = Convert.FromBase64String(iv);
        UTF8Encoding utf8 = new UTF8Encoding();
        string decryptedtext;

        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        using (ICryptoTransform decryptor = aes.CreateDecryptor(keyArray, ivArray))
        {
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
            byte[] bytes = Convert.FromBase64String(ciphertext);
            cs.Write(bytes, 0, bytes.Length);
            cs.FlushFinalBlock();
            ms.Position = 0;
            bytes = new byte[ms.Length];
            ms.Read(bytes, 0, bytes.Length);
            decryptedtext = utf8.GetString(bytes);
        }
        return decryptedtext;
    }
    #endregion

    #region MD5加密
    /// <summary>
    /// MD5加密
    /// </summary>
    /// <param name="input">需要加密的字符串</param>
    /// <returns></returns>
    public static string MD5Encrypt(string input)
    {
        return MD5Encrypt(input, new UTF8Encoding());
    }

    /// <summary>
    /// MD5加密
    /// </summary>
    /// <param name="input">需要加密的字符串</param>
    /// <param name="encode">字符的编码</param>
    /// <returns></returns>
    public static string MD5Encrypt(string input, Encoding encode)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] t = md5.ComputeHash(encode.GetBytes(input));
        StringBuilder sb = new StringBuilder(32);
        for (int i = 0; i < t.Length; i++)
            sb.Append(t[i].ToString("x").PadLeft(2, '0'));
        return sb.ToString();
    }

    /// <summary>
    /// MD5对文件流加密
    /// </summary>
    /// <param name="sr"></param>
    /// <returns></returns>
    public static string MD5Encrypt(Stream stream)
    {
        MD5 md5serv = MD5CryptoServiceProvider.Create();
        byte[] buffer = md5serv.ComputeHash(stream);
        StringBuilder sb = new StringBuilder();
        foreach (byte var in buffer)
            sb.Append(var.ToString("x2"));
        return sb.ToString();
    }

    /// <summary>
    /// MD5加密(返回16位加密串)
    /// </summary>
    /// <param name="input"></param>
    /// <param name="encode"></param>
    /// <returns></returns>
    public static string MD5Encrypt16(string input, Encoding encode)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        string result = BitConverter.ToString(md5.ComputeHash(encode.GetBytes(input)), 4, 8);
        result = result.Replace("-", "");
        return result;
    }
    #endregion

    #region 3DES 加密解密

    public static string DES3Encrypt(string data, string key)
    {
        TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

        DES.Key = Encoding.UTF8.GetBytes(key);
        //ASCIIEncoding.UTF8.GetBytes(key);
        DES.Mode = CipherMode.ECB;
        DES.Padding = PaddingMode.PKCS7;

        ICryptoTransform DESEncrypt = DES.CreateEncryptor();

        byte[] Buffer = Encoding.UTF8.GetBytes(data);
        return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
    }

    public static string DES3Decrypt(string data, string key)
    {
        TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

        DES.Key = Encoding.UTF8.GetBytes(key);
        DES.Mode = CipherMode.ECB;
        DES.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

        ICryptoTransform DESDecrypt = DES.CreateDecryptor();

        string result = "";
        try
        {
            byte[] Buffer = Convert.FromBase64String(data);
            result = Encoding.UTF8.GetString(DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }
        catch (Exception e)
        {

        }
        return result;
    }

    #endregion
}